package com.wef.system.service.impl;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.gfa4j.exception.ValidateRuntimeException;
import com.gfa4j.hibernate.BaseObject;
import com.gfa4j.service.impl.BaseServiceImpl;
import com.wef.system.entity.Role;
import com.wef.system.entity.RoleUser;
import com.wef.system.entity.User;
import com.wef.system.entity.domain.RoleUserDomain;
import com.wef.system.entity.domain.UserDomain;
import com.wef.system.service.UserService;

/**
 * @FileName UserServiceImpl.java
 * @Summary  功能描述：
 * @Author   KOO
 * @Version  1.0
 * @Date     2009/07/31
 * @example  使用示例：略。
 */

public class UserServiceImpl extends BaseServiceImpl implements UserService {

	public User addUser(User user){
		encryptPassword(user);
		return (User) super.saveObject(user);
	}

	public void deleteUser(User user) {
		removeOldRoleUser(user);
		super.deleteObject(user);
		
	}
	public List findUserRoleList(String userId){
		String hql = " select roleUser.role from RoleUser as roleUser where roleUser.user.userId = :userId ";
		return findByNamedParam(hql, "userId", userId);
	}

	public User saveOrUpdateUser(User user){	
		if (user.getRowStatus() == BaseObject.ROWSTATUS_ADDED) {
			return this.addUser(user);
		}
		if (user.getRowStatus() == BaseObject.ROWSTATUS_MODIFIED) {
			return this.updateUser(user);
		}
		if (user.getRowStatus() == BaseObject.ROWSTATUS_DELETED) {
			this.deleteUser(user);
			return null ;
		}
		return user;
	}

	public Set<User> saveOrUpdateUserWithRole(Set<User> users) {
		StringBuilder errorString = new StringBuilder();
		int i = 0;
		for (User user : users) {
			try {
				int operation = user.getRowStatus();
				
				if (operation == BaseObject.ROWSTATUS_ADDED || operation == BaseObject.ROWSTATUS_MODIFIED) {
					saveOrUpdateUser(user);
					updateUsersRoleUser(user,operation);
				}
				
				if (operation == BaseObject.ROWSTATUS_DELETED) {
					updateUsersRoleUser(user,operation);
					saveOrUpdateUser(user);
				}	
				i++;
			} catch (ValidateRuntimeException ex) {
				errorString.append(ex.getMessage() + "\n");
			}
		}
		if (errorString.length() > 0) {
			throw new ValidateRuntimeException(errorString.toString());
		}		
		
		return users;
	}
	
	public Set<User> saveOrUpdateUsers(Set<User> users){
		StringBuilder errorString = new StringBuilder();
		for (User user : users) {
			try {
				saveOrUpdateUser(user);
			} catch (ValidateRuntimeException ex) {
				errorString.append(ex.getMessage() + "\n");
			}
		}
		if (errorString.length() > 0) {
			throw new ValidateRuntimeException(errorString.toString());
		}
		return users;
	}

	public User updateUser(User user) {
		encryptPassword(user);
		return (User) super.updateObject(user);
	}
	
	private void  encryptPassword(User user){
		if (StringUtils.defaultString(user.getPassword()).length() <32){
			user.setPassword(LoginServiceImpl.encryptPassword(user.getPassword()));
		}
	}
	
	private void updateUsersRoleUser(User user,int operation){
		if (operation == BaseObject.ROWSTATUS_ADDED){
			if (user.getRoleUsers() != null && !user.getRoleUsers().isEmpty()){
				addNewRoleUser(user, user.getRoleUsers());
			}
		}
		if (operation == BaseObject.ROWSTATUS_MODIFIED){
			removeAddRoleUser(user);

		}
		if (operation == BaseObject.ROWSTATUS_DELETED){
			removeOldRoleUser(user);
		}
	}
	
	private void removeAddRoleUser(User user){
		List<RoleUser> oldRoleUsers = findByProperty(RoleUser.class, RoleUserDomain.user, user);
		
		for (Iterator listIt = oldRoleUsers.iterator(); listIt.hasNext();) {
			RoleUser roleUser = (RoleUser) listIt.next();
			if (user.getRoleUsers() != null) {
				for (Iterator setIt = user.getRoleUsers().iterator(); setIt.hasNext();) {
					RoleUser roleUser1 = (RoleUser)setIt.next();
					if(roleUser.getRole().getRoleId().equals(roleUser1.getRole().getRoleId())){
						roleUser.setRowStatus(BaseObject.ROWSTATUS_MODIFIED);
						roleUser1.setRowStatus(BaseObject.ROWSTATUS_MODIFIED);
						break;
					}
					
				}
			}
		}
		for (Iterator it = oldRoleUsers.iterator(); it.hasNext();) {
			RoleUser roleUser = (RoleUser) it.next();
			if(roleUser.getRowStatus()!=BaseObject.ROWSTATUS_MODIFIED)
				deleteObject(roleUser);
		}
		if (user.getRoleUsers() != null){
			for (Iterator it = user.getRoleUsers().iterator(); it.hasNext();) {
				RoleUser roleUser = (RoleUser)it.next();
				if(roleUser.getRowStatus()!=BaseObject.ROWSTATUS_MODIFIED){
				Role role = (Role)super.load(Role.class, roleUser.getRole().getRoleId()) ;
				roleUser.setRowStatus(BaseObject.ROWSTATUS_ADDED);
				roleUser.setRole(role);
				roleUser.setUser(user);
				saveObject(roleUser);
				}
			}
		}
	}
	
	private void removeOldRoleUser(User user){
		List oldRoleUsers = findByProperty(RoleUser.class, RoleUserDomain.user, user);
		if(oldRoleUsers.size()<1)
			return;
		for (Iterator it = oldRoleUsers.iterator(); it.hasNext();) {
			RoleUser roleUser = (RoleUser) it.next();
			deleteObject(roleUser);
		}
		getHibernateSession().flush();
	}
	
	private void addNewRoleUser(User user, Set<RoleUser> roleUsers){
		for (Iterator it = roleUsers.iterator(); it.hasNext();) {
			RoleUser roleUser = (RoleUser)it.next();
			Role role = (Role)super.load(Role.class, roleUser.getRole().getRoleId()) ;
			roleUser.setRowStatus(BaseObject.ROWSTATUS_ADDED);
			roleUser.setRole(role);
			roleUser.setUser(user);
			saveObject(roleUser);
		}
	}

	public boolean validateUserCodeExist(String userCode){
		List lst = findByProperty(User.class, UserDomain.userCode, userCode);
		if(lst.size() > 0){
			return true;
		}
		return false;
	}	

}
